package com.example.demo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.javax.el.ExpressionFactory;
import org.activiti.engine.impl.javax.el.ValueExpression;
import org.activiti.engine.impl.juel.ExpressionFactoryImpl;
import org.activiti.engine.impl.juel.SimpleContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.dao.Project_detailsMapper;
import com.example.demo.domain.Project_details;


public class helloworld {

	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	@Autowired
	Project_detailsMapper project_detailsMapper;
	//部署流程定义
	@Test 
	public void deploymentProcessDefinition() {
		Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的service、
							.createDeployment()//创建一个部署对象 
							.name("并行网管")//添加部署的名称
							.addClasspathResource("processes/parallelGateway.bpmn")//从classpath中加载静态文件，一次只能加载一个文件
							.addClasspathResource("processes/parallelGateway.png")//从classpath中加载静态文件，一次只能加载一个文件 

							.deploy();//完成部署 System.out.println(deployment.getId());
			System.out.println(deployment.getName()); 
			System.out.println(deployment.getId()); 
	}
		 
	


	//流程实例id:2501
	//流程定义id:testProcess:1:4
	//启动流程实例
	@Test
	public void startProcessInstance() {
		//流程定义的key
		String processDefinitiionKey = "Parallel";	
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("user_id", "g");
		ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的service
						.startProcessInstanceByKey(processDefinitiionKey,variables);//使用流程定义的KEY启动流程实例
		System.out.println("流程实例id:" + pi.getId());//流程实例id
		System.out.println("流程定义id:" + pi.getProcessDefinitionId());//流程定义id
	}
	
	/**查询当前人的个人任务*/
	@Test
	public void findMyPersonalTask(){
		String assignee = "3";
		List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
						.createTaskQuery()//创建任务查询对象
						.taskAssignee(assignee)//指定个人任务查询，指定办理人
						.list();
		if(list!=null && list.size()>0){
			for(Task task:list){
				System.out.println("任务ID:"+task.getId());
				System.out.println("任务名称:"+task.getName());
				System.out.println("任务的创建时间:"+task.getCreateTime());
				System.out.println("任务的办理人:"+task.getAssignee());
				System.out.println("流程实例ID："+task.getProcessInstanceId());
				System.out.println("执行对象ID:"+task.getExecutionId());
				System.out.println("流程定义ID:"+task.getProcessDefinitionId());
				System.out.println("项目名称:"+task.getProcessVariables());
				System.out.println("########################################################");
			}
		}
	}
	
	/**删除流程实例*/
	@Test
	public void delete(){
		processEngine.getRuntimeService().deleteProcessInstance("5001", "删除原因");//删除流程
	}
	
	/**完成我的任务*/
	@Test
	public void completeMyPersonalTask(){

		//任务ID
		String taskId = "40005";
		//设置下一个任务执行人的流程变量
		TaskService taskService = processEngine.getTaskService();
		taskService.setVariable(taskId, "1", "1");
		taskService.setVariable(taskId, "2", "2");
		taskService.setVariable(taskId, "3", "3");
		//taskService.setVariable(taskId, "yfbbz_id", "研发部部长");
		//taskService.setVariable(taskId, "user_id", "duanshihao");
		Task task=taskService.createTaskQuery().taskId(taskId).singleResult();// 使用任务id,获取任务对象，获取流程实例id
		//taskService.addComment(taskId, task.getProcessInstanceId(), "标定部部长审批");//填写任务备注
		//taskService.setVariable(taskId, "approval", "1");//o为通过 1为驳回s
		taskService.setVariable(taskId, "user_id", "huchao");//o为通过 1为驳回s
		taskService.complete(taskId);//完成任务
		
		System.out.println("完成任务：任务ID："+taskId);
	}
	
	/**完成我的任务*/
	@Test
	public void haha(){
		TaskService taskService = processEngine.getTaskService();
		RuntimeService runtimeService = processEngine.getRuntimeService();
		HistoryService historyService = processEngine.getHistoryService();
		//任务ID
		String taskId = "2501";
		List<Comment> historyCommnets = new ArrayList<>();
      List<HistoricActivityInstance> hais = historyService.createHistoricActivityInstanceQuery().processInstanceId(taskId).activityType("userTask").list();
      //     3）查询每个历史任务的批注
      for (HistoricActivityInstance hai : hais) {
          String historytaskId = hai.getTaskId();
          List<Comment> comments = taskService.getTaskComments(historytaskId);
          // 4）如果当前任务有批注信息，添加到集合中
          if(comments!=null && comments.size()>0){
              historyCommnets.addAll(comments);
          }
      }
		for(int i = 0; i < historyCommnets.size(); i ++) {
			System.out.println("完成任务：任务ID："+ historyCommnets.get(i).getFullMessage() +"     "+ historyCommnets.get(i).getId() +"     "+ historyCommnets.get(i).getTaskId() +"     "+ historyCommnets.get(i).getType());
		}
	}
	
	/**查询历史流程实例*/
	@Test
	public void findHistoryProcessInstance(){
		String processInstanceId = "35001";
		HistoricProcessInstance hpi = processEngine.getHistoryService()//与历史数据（历史表）相关的Service act_hi_procinst
						.createHistoricProcessInstanceQuery()//创建历史流程实例查询
						.processInstanceId(processInstanceId)//使用流程实例ID查询
						.orderByProcessInstanceStartTime().asc()
						.singleResult();
		System.out.println(hpi.getId()+"    "+hpi.getProcessDefinitionId()+"   "+hpi.getName()+"    "+hpi.getStartTime()+"    "+hpi.getEndTime()+"     "+hpi.getDurationInMillis());
	}
	
	/**查询历史活动*/  
	@Test
	public void findHistoryActiviti(){
		String processInstanceId = "270017";
		List<HistoricActivityInstance> list = processEngine.getHistoryService()// act_hi_actinst
						.createHistoricActivityInstanceQuery()//创建历史活动实例的查询
						.processInstanceId(processInstanceId)//
						.orderByHistoricActivityInstanceStartTime().asc()//
						.list();
		if(list!=null && list.size()>0){
			for(HistoricActivityInstance hai:list){                                                                                           
				System.out.println(hai.getActivityType()+" "+hai.getAssignee()+" "+hai.getActivityName()+"    "+hai.getStartTime()+"   "+hai.getEndTime());
				System.out.println("#####################");
			}
		}
	}


	/**删除流程实例*/
	@Test
	public void iiii(){
		//任务ID
		String taskId = "17508";
		String procInstanceId = "";
		TaskService taskService = processEngine.getTaskService();		
		ProcessDefinitionEntity processDefinitionEntity = null; 
		String id = null;
	}
	
	@Test
    public void nextTaskInfo() throws Exception{
		helloworld task = new helloworld();
        String processInstanceId = "65005";
        TaskDefinition nextTaskGroup = task.getNextTaskInfo(processInstanceId);
        System.out.println(nextTaskGroup.getKey());
        //System.out.println(nextTaskGroup.get(1).getKey());
    }
	
	/** 
     * 获取下一个用户任务信息  
     * @param String taskId     任务Id信息  
     * @return  下一个用户任务用户组信息  
     * @throws Exception 
     */  
    public TaskDefinition getNextTaskInfo(String taskId) throws Exception {  

        ProcessDefinitionEntity processDefinitionEntity = null;  

        String id = null;  

        TaskDefinition task = null;  

        //获取流程实例Id信息   
        String processInstanceId = processEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();  
        String ssss= "dsadsad";
        //获取流程发布Id信息   
        String definitionId = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();  

        processDefinitionEntity = (ProcessDefinitionEntity)processEngine.getRepositoryService().getProcessDefinition(definitionId);;  

        ExecutionEntity execution = (ExecutionEntity) processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  

        //当前流程节点Id信息   
        String activitiId = execution.getActivityId();    

        //获取流程所有节点信息   
        List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();   

        //遍历所有节点信息   
        for(ActivityImpl activityImpl : activitiList){      
            id = activityImpl.getId();     
            if (activitiId.equals(id)) {
                //获取下一个节点信息   
                task = nextTaskDefinition(activityImpl, activityImpl.getId(), null, processInstanceId); 
                break;
            }
        }  
        return task;  
    }  

    /**  
     * 下一个任务节点信息,  
     *  
     * 如果下一个节点为用户任务则直接返回,  
     *  
     * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,  
     * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务
     * @param ActivityImpl activityImpl     流程节点信息  
     * @param String activityId             当前流程节点Id信息  
     * @param String elString               排他网关顺序流线段判断条件
     * @param String processInstanceId      流程实例Id信息  
     * @return  
     */    
    private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){   
    	List<Map<String, Object>> listMap = new ArrayList<Map<String,Object>>();
    	Map<String, Object> map = new HashMap();
        PvmActivity ac = null;

        Object s = null;

        // 如果遍历节点为用户任务并且节点不是当前节点信息
        if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
            // 获取该节点下一个节点信息
            TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
                    .getTaskDefinition();
            return taskDefinition;
        } else {
            // 获取节点所有流向线路信息
            List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
            ac = outTransitions.get(0).getDestination(); // 获取线路的终点节点
            if ("parallelGateway".equals(ac.getProperty("type"))){
            	  for (PvmTransition tr : outTransitions) {
                      System.out.println(ac.getProperty("type"));
                      System.out.println(ac.getId());
                      System.out.println(ac.getProperty("name"));
                  	map.put("id", ac.getId());
                	map.put("type", ac.getProperty("name"));
                	listMap.add(map);
                	continue;
            	  }
                  return null;
            } else if ("userTask".equals(ac.getProperty("type"))) {
                return null;
            }
            return null;
        }
    }  

    /** 
     * 查询流程启动时设置排他网关判断条件信息  
     * @param String gatewayId          排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息  
     * @param String processInstanceId  流程实例Id信息  
     * @return 
     */  
    public String getGatewayCondition(String gatewayId, String processInstanceId) {  
        Execution execution = processEngine.getRuntimeService().createExecutionQuery().processInstanceId(processInstanceId).singleResult();
        Object object= processEngine.getRuntimeService().getVariable(execution.getId(), gatewayId);
        return object==null? "":object.toString();  
    }  

    /** 
     * 根据key和value判断el表达式是否通过信息  
     * @param String key    el表达式key信息  
     * @param String el     el表达式信息  
     * @param String value  el表达式传入值信息  
     * @return 
     */  
    public boolean isCondition(String key, String el, String value) {  
        ExpressionFactory factory = new ExpressionFactoryImpl();    
        SimpleContext context = new SimpleContext();    
        context.setVariable(key, factory.createValueExpression(value, String.class));    
        ValueExpression e = factory.createValueExpression(context, el, boolean.class);    
        return (Boolean) e.getValue(context);  
    } 
    
    @Test
    public void dsadsssssds(){
    	List<HistoricTaskInstance> taskList = processEngine.getHistoryService().createHistoricTaskInstanceQuery().taskAssignee("9").finished().list();
    	RuntimeService runtimeService = processEngine.getRuntimeService();
    	Set<String> processInstanceSet = new HashSet<String>();
    	List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
    	for(HistoricTaskInstance hti : taskList) {   			
    		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(hti.getProcessInstanceId()).singleResult();
    		if(processInstance == null) {
    			processInstanceSet.add(hti.getProcessInstanceId());
    		}
    	}  
    	List<HistoricProcessInstance> lists = processEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceIds(processInstanceSet).finished().list();
    	for(HistoricProcessInstance hpi: lists) {
    		System.out.println(hpi.getId());
    	}   	
    }
    public static void main(String [] arg) {
    	String transfer= "[{Assignee=54, condition=-2, taskName=整车标定驾驶性}, {Assignee=57, condition=-1, taskName=整车标定obd}, {Assignee=59, condition=-3, taskName=整车标定三高}]";	
    	JSONObject json = new JSONObject();
    	
    	Map map = new HashMap<>();
    	map.put("transfer", json.parseObject(transfer));
    	List<Map> list= JSONArray.parseArray(map.get("transfer").toString(),Map.class);
    	System.out.println(list);
    }
}
